from manim import *

# manim -qm -v WARNING QuadraticAnimationWithAxis.py
class QuadraticAnimationWithAxis(Scene):
    def construct(self):
        # 创建坐标轴
        axes = Axes(
            x_range=[-3, 3, 1],
            y_range=[-30, 100, 10],
            axis_config={"color": BLUE},
            x_axis_config={"numbers_to_include": np.arange(-3, 4, 1)},
            y_axis_config={"numbers_to_include": np.arange(-30, 101, 10)},
        )
        axes.add_coordinates()
        axis_labels = axes.get_axis_labels(x_label="x", y_label="y")

        # 固定系数
        a = 10
        b = 10
        c = -10  # 初始常数项值

        # 计算对称轴位置 x = -b/(2a)
        def get_vertex_x():
            return -b / (2 * a)

        # 创建函数曲线
        graph = axes.plot(lambda x: a*x**2 + b*x + c, color=YELLOW)
        
        # 创建对称轴（垂直线）
        vertex_x = get_vertex_x()
        axis_of_symmetry = DashedLine(
            start=axes.c2p(vertex_x, axes.y_range[0]),
            end=axes.c2p(vertex_x, axes.y_range[1]),
            color=RED,
            stroke_width=2
        )
        # axis_label = MathTex(f"x = {vertex_x:.2f}").next_to(axis_of_symmetry, UP, buff=0.1).set_color(RED)
        axis_label = MathTex("x = -b/(2a)").next_to(axis_of_symmetry, UP*1.1, buff=0.1).set_color(RED)

        # 创建函数表达式
        equation = MathTex("y = ","10","x^2 + ","10","x + ","-10").next_to(axis_labels, UP*0.01)
        equation[1].set_color(RED)
        equation[3].set_color(GREEN)
        equation[5].set_color(BLUE)

        # 创建常数项显示
        c_value = DecimalNumber(c, num_decimal_places=1, include_sign=True, color=BLUE)
        c_label = VGroup(Text("c = ", color=BLUE), c_value).arrange(RIGHT).next_to(equation, DOWN)

        # 动画开始
        self.play(Create(axes), Write(axis_labels), run_time=2)
        self.play(
            Create(graph),
            Create(axis_of_symmetry),
            Write(axis_label),
            Write(equation),
            Write(c_label),
            run_time=2
        )
        self.wait(1)

        # 动态更新常数项
        for new_c in np.arange(-10, 10.1, 0.1):
            new_graph = axes.plot(lambda x: a*x**2 + b*x + new_c, color=YELLOW)
            
            # 更新方程显示
            new_equation = MathTex("y = ","10","x^2 + ","10","x + ",f"{new_c:.1f}").next_to(axis_labels, UP*0.01)
            new_equation[1].set_color(RED)
            new_equation[3].set_color(GREEN)
            new_equation[5].set_color(BLUE)
            
            # 更新c值显示
            new_c_value = DecimalNumber(new_c, num_decimal_places=1, include_sign=True, color=BLUE)
            new_c_label = VGroup(Text("c = ", color=BLUE), new_c_value).arrange(RIGHT).next_to(new_equation, DOWN)

            # 对称轴位置不变（因为a和b不变），但需要重新创建以确保正确显示
            new_axis = DashedLine(
                start=axes.c2p(vertex_x, axes.y_range[0]),
                end=axes.c2p(vertex_x, axes.y_range[1]),
                color=RED,
                stroke_width=2
            )
            new_axis_label = MathTex(f"x = {vertex_x:.2f}").next_to(new_axis, UP*1.1, buff=0.1).set_color(RED)

            self.play(
                Transform(graph, new_graph),
                Transform(equation, new_equation),
                Transform(c_label, new_c_label),
                Transform(axis_of_symmetry, new_axis),
                Transform(axis_label, new_axis_label),
                rate_func=linear,
                run_time=0.05
            )

        self.wait(3)

if __name__ == "__main__":
    scene = QuadraticAnimationWithAxis()
    scene.render()